package org.zjh.model;

import org.zjh.common.PokerType;
import org.zjh.controller.GameController;
import org.zjh.utils.PokerUtil;

import org.zjh.view.game.GamePanel;
import org.zjh.view.ui.GameUi;


import java.awt.*;
import java.util.ArrayList;

import static org.zjh.common.GameCommon.checkDiscardBoom;

/**
 * 真人玩家类
 */
public class RealPlayer extends Player {

    //账号
    private String account;
    //密码
    private String password;
    //是否在托管 true 托管状态  false 不是托管状态
    private boolean isHosted = false; //默认 false

    public RealPlayer() {
    }


    public RealPlayer(String nickname, String account, String password, int score) {
        super(nickname, score);
        this.account = account;
        this.password = password;

    }


    /**
     * 实际玩家叫分方法
     */
    @Override
    public void callPoint(Player player) {
        GamePanel gamePanel = GameUi.gameFrame.getGamePanel();
        //获取场上倍数
        int multiple = Integer.parseInt(gamePanel.getMultipleJLabel().getText().substring(3));
        showPointChoice(gamePanel, multiple);
    }


    /**
     * 展示对应的分值选项
     * @param gamePanel 游戏面板
     * @param multiple 倍数
     */
    private void showPointChoice(GamePanel gamePanel, int multiple) {
        if (multiple == 0) {
            gamePanel.setCallPointJLabelVisibleTrue();
        } else if (multiple == 1) {
            gamePanel.setCallPointJLabelVisibleTrue();
            gamePanel.getOnePointJLabel().setVisible(false);
        } else if (multiple == 2) {
            gamePanel.getThreePointJLabel().setVisible(true);
            gamePanel.getNoCallJLabel().setVisible(true);
        }
    }


    @Override
    public boolean isSuccessCallPoint() {
        return !GameUi.gameFrame.getGamePanel().getRealPlayerCallPointResultJLabel().getText().isEmpty();
    }



    /**
     * 出牌方法
     */

    @Override
    public void discardPoker() {

        //获取自己 要出的牌
        ArrayList<Poker> discardPokerList = getDiscardPokerList();
        // 获取当前出牌的牌型
        PokerType pokerType = PokerUtil.judgePokerType(getDiscardPokerList());

        // 判断牌型是否合法
        if (pokerType == PokerType.P0) {
            //将扑克牌落回原来位置
            downDiscardPoker(discardPokerList);
            //将要出手牌集合清空
            discardPokerList.clear();
            return;
        }

        // 获取当前出牌的大小
        int discardPokerValue = PokerUtil.calculatePokerValueBasedOnType(getDiscardPokerList(), pokerType);
        // 获取当前牌桌上的出牌
        GameController gameController = GameController.getInstance();
        ArrayList<Poker> nowDeskPokerList = gameController.getNowDeskPokerList();

        if (nowDeskPokerList.isEmpty()) { // 当前牌桌上没有牌
            // 直接出牌
            executeDiscard(discardPokerList);
        } else { // 当前桌面上有牌

            //首先判断 牌桌上的是否是自己出的牌
            if (nowDeskPokerList.get(0).getOwnerId().equals("REAL")){
                //是实际玩家出的牌 那么可以随意出牌
                executeDiscard(discardPokerList);
            }
            else{ //不是自己出牌的 需要判断
                PokerType nowDeskPokerType = PokerUtil.judgePokerType(nowDeskPokerList);
                int nowDeskPokerValue = PokerUtil.calculatePokerValueBasedOnType(nowDeskPokerList, nowDeskPokerType);

                if (pokerType == PokerType.P4) { // 炸弹可以对应任何牌型
                    // 如果当前牌桌上也是炸弹，比较大小
                    if (nowDeskPokerType == PokerType.P4) {
                        if (discardPokerValue > nowDeskPokerValue) {
                            executeDiscard(discardPokerList);
                        }else{
                            // 没有桌面上牌大 降回手牌
                            downDiscardPoker(discardPokerList);
                        }
                    } else { // 当前牌桌上不是炸弹
                        executeDiscard(discardPokerList);
                    }
                } else { // 当前出牌类型不是炸弹
                    // 需要和当前牌桌上的牌型对应 并且 出牌数量也要对应 大小也需要比桌面上的牌值大
                    if (pokerType == nowDeskPokerType && discardPokerValue > nowDeskPokerValue && discardPokerList.size() == nowDeskPokerList.size()) {
                        executeDiscard(discardPokerList);
                    } else {
                        //出牌不合理 将出牌集合中的所有牌落下
                        downDiscardPoker(discardPokerList);
                    }
                }
            }



        }
    }

    /**
     * 降回手牌
     * @param discardPokerList 出牌集合
     */
    public void downDiscardPoker(ArrayList<Poker> discardPokerList){
        //将扑克牌落回原来位置
        for (Poker poker : discardPokerList) {
            Point location = poker.getLocation();
            location.y = 500;
            poker.setClicked(false);
            poker.setLocation(location);
        }
        //将要出手牌集合清空
        discardPokerList.clear();
    }


    /**
     * 上升手牌
     * @param discardPokerList 出牌集合
     */
    public void upDiscardPoker(ArrayList<Poker> discardPokerList){
        //将扑克牌升起
        for (Poker poker : discardPokerList) {
            Point location = poker.getLocation();
            location.y = 470;
            poker.setClicked(true);
            poker.setLocation(location);
        }
    }


    /**
     * 成功出牌
     * @param discardPokerList 出的手牌
     */
    private void executeDiscard(ArrayList<Poker> discardPokerList) {
        //检查是否 出的是炸弹 是的话 倍数翻倍
        checkDiscardBoom(discardPokerList);

        // 出牌成功 移动牌
        setDiscardPokerOver(true);
        //从当前手牌中移除 出牌集合中的牌
        getPokerList().removeAll(discardPokerList);

        //移动要出的手牌
        PokerUtil.moveDiscardPoker(this);


        //重新排序手牌
        PokerUtil.sortPoker(this);
        PokerUtil.pokerMove(this);

        GameController gameController = GameController.getInstance();
        ArrayList<Poker> nowDeskPokerList = gameController.getNowDeskPokerList();

        //将原先牌桌上的牌设置不可见
        for (Poker poker : nowDeskPokerList) {
            poker.setVisible(false);
        }

        // 将当前桌面上的牌赋值
        nowDeskPokerList.clear(); // 清空当前桌面牌
        nowDeskPokerList.addAll(discardPokerList); // 添加出牌
        //将出牌集合中 的牌设置不可点击
        PokerUtil.setCantBeClick(discardPokerList);
        // 清空当前要出的牌的集合
        discardPokerList.clear();
        //将不要标签重置
        GameUi.gameFrame.getGamePanel().resetNoDiscardPokerLabel();
    }


    public String getAccount() {
        return account;
    }

    public void setAccount(String account) {
        this.account = account;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public boolean isHosted() {
        return isHosted;
    }

    public void setHosted(boolean hosted) {
        isHosted = hosted;
    }
}
